package org.rsbot.script;

import java.util.EventListener;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rsbot.bot.Bot;
import org.rsbot.event.EventManager;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.script.internal.BreakHandler;
import org.rsbot.script.internal.ScriptHandler;
import org.rsbot.script.methods.Account;
import org.rsbot.script.methods.Bank;
import org.rsbot.script.methods.Game;
import org.rsbot.script.methods.MethodContext;
import org.rsbot.script.methods.Methods;
import org.rsbot.script.methods.Mouse;
import org.rsbot.script.randoms.LoginBot;
import org.rsbot.script.util.Timer;

public abstract class Script extends Methods
  implements EventListener, Runnable
{
  Set<Script> delegates = new HashSet();
  MethodContext ctx;
  private volatile boolean running = false;
  private volatile boolean paused = false;
  private volatile boolean random = false;

  private int id = -1;
  private long lastNotice;

  @Deprecated
  public final boolean onStart(Map<String, String> paramMap)
  {
    return true;
  }

  public boolean onStart()
  {
    return true;
  }

  public abstract int loop();

  public void onFinish()
  {
  }

  public final void init(Script paramScript)
  {
    init(paramScript.ctx);
  }

  public final void init(MethodContext paramMethodContext)
  {
    super.init(paramMethodContext);
    this.ctx = paramMethodContext;
  }

  public final void delegateTo(Script paramScript)
  {
    paramScript.init(this.ctx);
    this.ctx.bot.getEventManager().addListener(paramScript);
    this.delegates.add(paramScript);
  }

  public final void deactivate(int paramInt)
  {
    if (paramInt != this.id) {
      throw new IllegalStateException("Invalid id!");
    }
    this.running = false;
  }

  public final void setID(int paramInt)
  {
    if (this.id != -1) {
      throw new IllegalStateException("Already added to pool!");
    }
    this.id = paramInt;
  }

  public final void setPaused(boolean paramBoolean)
  {
    if ((this.running) && (!this.random)) {
      if (paramBoolean)
        blockEvents(true);
      else {
        unblockEvents();
      }
    }
    this.paused = paramBoolean;
  }

  public final boolean isPaused()
  {
    return this.paused;
  }

  public final boolean isRunning()
  {
    return this.running;
  }

  public final boolean isActive()
  {
    return (this.running) && (!this.paused) && (!this.random);
  }

  public void stopScript()
  {
    stopScript(false);
  }

  public void stopScript(boolean paramBoolean)
  {
    this.log.info("Script stopping...");
    if (paramBoolean) {
      if (this.bank.isOpen()) {
        this.bank.close();
      }
      if (this.game.isLoggedIn()) {
        this.game.logout(false);
      }
    }
    this.running = false;
  }

  public final void run() {
    boolean bool = false;
    try {
      bool = onStart();
    } catch (ThreadDeath localThreadDeath1) {
    } catch (Throwable localThrowable1) {
      this.log.log(Level.SEVERE, "Error starting script: ", localThrowable1);
    }
    if (bool) {
      this.running = true;
      this.ctx.bot.getEventManager().addListener(this);
      this.log.info("Script started.");
      try {
        while (true) if (this.running)
            if (!this.paused) {
              if (this.account.isTakingBreaks()) {
                BreakHandler localBreakHandler = this.ctx.bot.getBreakHandler();
                if (localBreakHandler.isBreaking()) {
                  if (System.currentTimeMillis() - this.lastNotice > 600000L) {
                    this.lastNotice = System.currentTimeMillis();
                    this.log.info("Breaking for " + Timer.format(localBreakHandler.getBreakTime()));
                  }
                  if ((this.game.isLoggedIn()) && (localBreakHandler.getBreakTime() > 60000L))
                    this.game.logout(true);
                  try
                  {
                    sleep(5000);
                  } catch (ThreadDeath localThreadDeath4) {
                    break label279;
                  }
                }

                localBreakHandler.tick();
              }

              if (checkForRandoms()) {
                continue;
              }
              int i = -1;
              try {
                i = loop();
              } catch (ThreadDeath localThreadDeath5) {
                break label279;
              } catch (Exception localException) {
                this.log.log(Level.WARNING, "Uncaught exception from script: ", localException);
              }
              if (i != -1)
              {
                try
                {
                  sleep(i);
                } catch (ThreadDeath localThreadDeath6) {
                  break label279;
                }
                continue;
              } } else {
              try {
                sleep(1000);
              }
              catch (ThreadDeath localThreadDeath2)
              {
              }
            } try
        {
          label279: onFinish();
        } catch (ThreadDeath localThreadDeath3) {
        } catch (RuntimeException localRuntimeException) {
          localRuntimeException.printStackTrace();
        }
      } catch (Throwable localThrowable2) {
        onFinish();
      }
      this.running = false;
      this.log.info("Script stopped.");
    } else {
      this.log.severe("Failed to start up.");
    }
    this.mouse.moveOffScreen();
    for (Script localScript : this.delegates) {
      this.ctx.bot.getEventManager().removeListener(localScript);
    }
    this.delegates.clear();
    this.ctx.bot.getEventManager().removeListener(this);
    this.ctx.bot.getScriptHandler().stopScript(this.id);
    this.id = -1;
  }

  private boolean checkForRandoms() {
    if (this.ctx.bot.disableRandoms) {
      return false;
    }
    for (Random localRandom : this.ctx.bot.getScriptHandler().getRandoms()) {
      if ((localRandom.isEnabled()) && ((!this.ctx.bot.disableAutoLogin) || (!(localRandom instanceof LoginBot))) && 
        (localRandom.activateCondition())) {
        this.random = true;
        blockEvents(false);
        localRandom.run(this);
        unblockEvents();
        this.random = false;
        return true;
      }
    }

    return false;
  }

  private void blockEvents(boolean paramBoolean) {
    for (Script localScript : this.delegates) {
      this.ctx.bot.getEventManager().removeListener(localScript);
      if ((paramBoolean) && ((localScript instanceof PaintListener))) {
        this.ctx.bot.getEventManager().addListener(localScript, 4096L);
      }
    }
    this.ctx.bot.getEventManager().removeListener(this);
    if ((paramBoolean) && ((this instanceof PaintListener)))
      this.ctx.bot.getEventManager().addListener(this, 4096L);
  }

  private void unblockEvents()
  {
    for (Script localScript : this.delegates) {
      this.ctx.bot.getEventManager().removeListener(localScript);
      this.ctx.bot.getEventManager().addListener(localScript);
    }
    this.ctx.bot.getEventManager().removeListener(this);
    this.ctx.bot.getEventManager().addListener(this);
  }
}